package bysj.controller.basic;

import bysj.domain.Degree;
import bysj.service.DegreeService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;

import lombok.extern.slf4j.Slf4j;
import util.Condition;
import util.JSONUtil;
import util.Pagination;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;
@Slf4j
@WebServlet("/degree.ctl")
public class DegreeController extends HttpServlet {
    //请使用以下JSON测试增加功能（id为空）
    //{"description":"id为null的新学位","no":"05","remarks":""}
    //请使用以下JSON测试修改功能
    //{"description":"修改id=1的学位","id":1,"no":"05","remarks":""}

    /**
     * POST, http://localhost:8080/degree.ctl, 增加学位
     * 增加一个学位对象：将来自前端请求的JSON对象，增加到数据库表中
     * @param request 请求对象
     * @param response 响应对象
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        
        //根据request对象，获得代表新增Teacher的JSON字串
        String req_teacherToAdd_jsonStr = JSONUtil.getJSON(request);
        //将JSON字串解析为Teacher对象
        Degree degreeToAdd = JSON.parseObject(req_teacherToAdd_jsonStr,
                Degree.class);
        //创建JSON对象respMessage_jsonObj，以便往前端响应信息
        JSONObject respMessage_jsonObj = new JSONObject();
        try {
            //在数据库表中增加Teacher对象
            DegreeService.getInstance().add(degreeToAdd);
            respMessage_jsonObj.put("message", "增加成功");
        } catch (SQLException e) {
            respMessage_jsonObj.put("message", "数据库操作异常");
            //打印异常栈，方便调试（要用log4j代替）
            log.error(e.getMessage());
        } catch (Exception e) {
            respMessage_jsonObj.put("message", "网络异常");
            //打印异常栈，方便调试（要用log4j代替）
            log.error(e.getMessage());
        }
        //响应respMessage_jsonObj到前端
        response.getWriter().println(respMessage_jsonObj);
    }

    /**
     * DELETE, http://localhost:8080/degree.ctl?id=1, 删除id=1的学位
     * 删除一个学位对象：根据来自前端请求的id，删除数据库表中id的对应记录
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doDelete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //将request参数转换为JSON字串
        String request_json_str = JSONUtil.getJSON(request);
        //将请求body解析为要删除的Teacher的id对应的JSONObject对象(可能是{"id":1})
        JSONObject idOfDegreeToDelete_jsonObj = JSON.parseObject(request_json_str);
        //从JSONObject对象中读取键“id”的值（Java Object对象），
        Object id_obj = idOfDegreeToDelete_jsonObj.get("id");
        int id_int = Integer.parseInt(id_obj.toString());
        System.out.println("id=" + id_int);//用于调试，要使用log4j代替
        
        //创建JSON对象respMessage_jsonObj，以便往前端响应信息
        JSONObject respMessage_jsonObj = new JSONObject();
        try {
            //到数据库表中删除对应的教师
            DegreeService.getInstance().delete(id_int);
            respMessage_jsonObj.put("message", "删除成功");
        } catch (SQLException e) {
            respMessage_jsonObj.put("message", "数据库操作异常");
            //打印异常栈，方便调试（要用log4j代替）
            log.error(e.getMessage());
        } catch (Exception e) {
            respMessage_jsonObj.put("message", "网络异常");
            //打印异常栈，方便调试（要用log4j代替）
            log.error(e.getMessage());
        }
        //响应respMessage_jsonObj到前端
        response.getWriter().println(respMessage_jsonObj);
    }


    /**
     * PUT, http://localhost:8080/degree.ctl, 修改学位
     *
     * 修改一个学位对象：将来自前端请求的JSON对象，更新数据库表中相同id的记录
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doPut(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String degreeToUpdate_jsonStr = JSONUtil.getJSON(request);
        //将JSON字串解析为要修改的Teacher对象（有id的完整对象）
        Degree degreeToUpdate = JSON.parseObject(degreeToUpdate_jsonStr, Degree.class);
        //////设置响应字符编码为UTF-8
        response.setContentType("application/json;charset=UTF-8");
        //创建JSON对象respMessage_jsonObj，以便往前端响应信息
        JSONObject respMessage_jsonObj = new JSONObject();
        try {
            //到数据库表修改Teacher对象对应的记录
            DegreeService.getInstance().update(degreeToUpdate);
            respMessage_jsonObj.put("message", "修改成功");
        } catch (SQLException e) {
            respMessage_jsonObj.put("message", "数据库操作异常");
            //打印异常栈，方便调试（要用log4j代替）
            log.error(e.getMessage());
        } catch (Exception e) {
            respMessage_jsonObj.put("message", "网络异常");
            //打印异常栈，方便调试（要用log4j代替）
            log.error(e.getMessage());
        }
        //响应respMessage_jsonObj到前端
        response.getWriter().println(respMessage_jsonObj);
    }

    /**
     * GET, http://localhost:8080/degree.ctl?id=1, 查询id=1的学位
     * GET, http://localhost:8080/degree.ctl, 查询所有的学位
     * 把一个或所有学位对象响应到前端
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException
     */
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
            //创建JSON对象respMessage_jsonObj，以便往前端响应信息
            JSONObject respMessage_jsonObj = new JSONObject();
            //将request body转换为JSON字串
            String req_jsonStr = JSONUtil.getJSON(request);
            //将request body解析为JSONObject对象
            JSONObject req_jsonObj = JSON.parseObject(req_jsonStr);
            //如果请求body为空
            if (req_jsonObj == null) {
                respMessage_jsonObj.put("message","未收到请求信息！");
                response.getWriter().println(respMessage_jsonObj);
                return;
            }
            //从JSONObject对象中读取键“id”的值（Java Object对象），req_jsonObj可能是{"id":1}
            Object id_obj = req_jsonObj.get("id");
            try {
                //如果id_Obj != null, 说明请求数据有id键，是请求某个教师对象
                if (id_obj != null) {
                    int id_int = Integer.parseInt(id_obj.toString());
                    responseDegree(id_int, response);
                } else {//请求中包含条件和分页信息，需要响应多个教师对象
                    //读取分页信息，形成分页对象
                    //从JSONObject对象中读取 “pagination” 键对应的值(JSONObject对象)
                    Pagination pagination = getPagination(req_jsonObj);
                    //从请求JSONObject对象中读取键“conditionList”对应的值(描述查询条件的JSONArray对象)
                    List<Condition> conditionList = getConditions(req_jsonObj);
                    //响应多个教师信息，其中conditionList, pagination两个对象引用为空是可能的
                    this.responseDegrees(response, conditionList, pagination);
                }
            } catch (SQLException e) {
                respMessage_jsonObj.put("message", "数据库操作异常");
                //响应respMessage_jsonObj到前端
                response.getWriter().println(respMessage_jsonObj);
                //打印异常栈，方便调试（要用log4j代替）
                log.error(e.getMessage());
            } catch (Exception e) {
                respMessage_jsonObj.put("message", "网络异常");
                //响应respMessage_jsonObj到前端
                response.getWriter().println(respMessage_jsonObj);
                //打印异常栈，方便调试（要用log4j代替）
                log.error(e.getMessage());
            }
        }
        /**
         * 获得代表查询条件的List对象
         * @param req_jsonObj 请求body对应的JSONObject对象
         * @return 代表查询条件的List对象
         */
        private List<Condition> getConditions(JSONObject req_jsonObj) {
            JSONArray conditionList_jsonArray =
                    req_jsonObj.getJSONArray("conditionList");
            //条件对象
            List<Condition> conditionList = null;
            //如果有“conditionList”键
            if (conditionList_jsonArray != null) {
                //将描述条件的 JSONArray 对象转换为 Java的List 对象
                conditionList = conditionList_jsonArray.toJavaList(Condition.class);
            }
            return conditionList;
        }
        /**
         * 获得代表查询条件的Pagination对象
         * @param req_jsonObj 请求body对应的JSONObject对象
         * @return 代表查询条件的Pagination对象
         */
        private Pagination getPagination(JSONObject req_jsonObj) {
            JSONObject pagination_jsonObj =
                    req_jsonObj.getJSONObject("pagination");
            //分页对象
            Pagination pagination = null;
            //如果有“pagination”键
            if (pagination_jsonObj != null) {
                //将描述分页的 JSONObject 对象转换为 Java 对象
                pagination = pagination_jsonObj
                        .toJavaObject(Pagination.class);
            }
            return pagination;
        }
    //响应一个学位对象
    private void responseDegree(int id, HttpServletResponse response)
            throws ServletException, IOException, SQLException {
        //根据id查找学位
        Degree degree = DegreeService.getInstance().find(id);
        String degree_json = JSON.toJSONString(degree);

        //响应degree_json到前端
        response.getWriter().println(degree_json);
    }
    //响应所有学位对象
    private void responseDegrees(HttpServletResponse response,List<Condition>conditionList,Pagination pagination)
            throws ServletException, IOException, SQLException {
        //分页获得所有学院
        Collection<Degree> degrees = DegreeService.getInstance().findAll(conditionList,pagination);
        String school_json = JSON.toJSONString(degrees, SerializerFeature.DisableCircularReferenceDetect);
        //创建JSON对象message，以便往前端响应totalNum和指定页的元组数数据
        JSONObject message = new JSONObject();
        //message.put("totalNum",pagination.getTotalNum());
        message.put("data",school_json);
        //响应schools_json到前端
        response.getWriter().println(message);
    }
}
